package com.promote.hotspot.server.window.fixed;

import java.time.LocalTime;
import java.util.concurrent.TimeUnit;

/**
 * 这段代码实现了一个简单的固定窗口速率限制器（FixedWindowRateLimiter）。
 * 其主要功能是限制在指定时间窗口内请求的次数不超过预设的限制值。
 */
public class FixedWindowRateLimiter {

    // 表示请求限制次数
    private final int requestsLimit;
    // 时间窗口的长度（以毫秒为单位）。
    private final long timeWindowInMillis;
    // 当前时间窗口内的请求数量
    private int count;
    // 用于记录当前时间窗口的起始时间
    private long windowStart;

    public FixedWindowRateLimiter(int requestsLimit, long timeWindowInMillis) {
        super();
        this.requestsLimit = requestsLimit;
        this.timeWindowInMillis = timeWindowInMillis;
        this.count = 0;
        this.windowStart = System.currentTimeMillis();
    }

    /**
     * 用于判断是否允许进行请求。该方法是同步的，确保了并发情况下的线程安全
     */
    public synchronized boolean allowRequest() {
        long current = System.currentTimeMillis();
        long timeElapsed = current - windowStart;
        // 如果时间差大于时间窗口长度，则重置时间窗口的起始时间为当前时间，并将请求数量 count 重置为 0
        if (timeElapsed > timeWindowInMillis) {
            windowStart = current;
            count = 0;
        }
        // 判断是否超过请求限制次数
        return ++count <= requestsLimit;
    }

    public static void main(String[] args) throws InterruptedException {
        // 设置请求限制次数为 1，时间窗口长度为 2 秒
        FixedWindowRateLimiter rateLimiter = new FixedWindowRateLimiter(1, TimeUnit.SECONDS.toMillis(2));
        for (int i = 0; i < 10; i++) {
            Thread.sleep(50);
            LocalTime now = LocalTime.now();
            if (!rateLimiter.allowRequest()) {
                System.out.println(now + " Request denied");
            } else {
                System.out.println(now + " Request allowed");
            }
        }
    }
}